package jehc.djshi.workflow.design.mxUtils;

import cn.hutool.core.collection.CollectionUtil;
import jehc.djshi.common.util.JsonUtil;
import jehc.djshi.common.util.StringUtil;
import jehc.djshi.workflow.design.mxUtils.communal.MxMultiInstanceUtils;
import jehc.djshi.workflow.design.mxUtils.communal.MxUtils;
import jehc.djshi.workflow.design.mxUtils.vo.EventNode;
import jehc.djshi.workflow.design.mxUtils.vo.Field;
import jehc.djshi.workflow.design.mxUtils.vo.FormNode;
import jehc.djshi.workflow.design.mxUtils.vo.GraphNode;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Element;

import java.util.List;
import java.util.Map;

/**
 * @Desc 人工任务
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Slf4j
public class MxUserTask {
	/**
	 * 任务节点操作
	 * @param root
	 * @param mxCellList
	 * @param mxCell
	 * @return
	 */
	public static String userTask(Element root,List mxCellList,Element mxCell){
		String task_node = "";
		/////////////基本属性开始/////////////
 		String name = mxCell.attributeValue("value");
 		String nodeID = mxCell.attributeValue("nodeID");
 		/////////////基本属性结束/////////////
 		
 		/////////////主要配置开始/////////////
 		String assignee = mxCell.attributeValue("assignee");
 		String candidateUsers = mxCell.attributeValue("candidateUsers");
 		String candidateGroups = mxCell.attributeValue("candidateGroups");
 		String Expression = mxCell.attributeValue("Expression");
 		String formKey = mxCell.attributeValue("formKey");
 		String dueDate = mxCell.attributeValue("dueDate"); 
 		String priority = mxCell.attributeValue("priority");
 		String asynchronous = mxCell.attributeValue("asynchronous");
 		String isForCompensation =  mxCell.attributeValue("isForCompensation");//是否补偿边界
 		
 		String event_node_value = mxCell.attributeValue("event_node_value");/**监听事件属性**/
 		/////////////主要配置结束/////////////
 		
 		//节点中其他基本属性
 		//获取mxCell节点下的mxGeometry节点
        Element mxGeometry = mxCell.element("mxGeometry"); 
        String x = mxGeometry.attributeValue("x");
        String y = mxGeometry.attributeValue("y");
        if(null == y || "".equals(y)){
        	y = "0";
        }
        if(null == x || "".equals(x)){
        	x = "0";
        }
        
        if(!StringUtil.isEmpty(assignee)){
        	assignee = " activiti:assignee='"+assignee+"'";
        }else{
        	assignee=" ";
        }
        if(!StringUtil.isEmpty(candidateUsers)){
        	candidateUsers = " activiti:candidateUsers='"+candidateUsers+"'";
        }else{
        	candidateUsers=" ";
        }
        if(!StringUtil.isEmpty(candidateGroups)){
        	candidateGroups = " activiti:candidateGroups='"+candidateGroups+"'";
        }else{
        	candidateGroups=" ";
        }
        if(!StringUtil.isEmpty(Expression)){
        	Expression = " aactiviti:skipExpression='"+Expression+"'";
        }else{
        	Expression=" ";
        }
        if(!StringUtil.isEmpty(dueDate)){
        	dueDate = " activiti:dueDate='"+dueDate+"'";
        }else{
        	dueDate="";
        }
        if(!StringUtil.isEmpty(formKey)){
        	formKey = " activiti:formKey='"+formKey+"'";
        }else{
        	formKey=" ";
        }
        if(!StringUtil.isEmpty(priority)){
        	priority = " activiti:priority='"+priority+"'";
        }else{
        	priority=" ";
        }
        if(!StringUtil.isEmpty(asynchronous) && "0".equals(asynchronous)){
        	asynchronous = " activiti:async='true'";
        }else{
        	asynchronous=" ";
        }
        if(!StringUtil.isEmpty(isForCompensation) && "1".equals(isForCompensation)){
        	isForCompensation = " isForCompensation='true'";
        }else{
        	isForCompensation=" ";
        }
        
		//开区间
        task_node+="<userTask id='"+nodeID+"' name='"+name+"' "+asynchronous+assignee+candidateUsers+candidateGroups+Expression+dueDate+formKey+priority+isForCompensation+">";
        task_node+=MxUtils.documentation(mxCell);
        //****开始区间与闭区间属性 开始****//
        task_node += "<extensionElements>";
        //监听器配置开始 总循环操作
        if(!StringUtil.isEmpty(event_node_value)){
        	//主列表
			GraphNode graphNode = JsonUtil.fromAliFastJson(event_node_value,GraphNode.class);
			List<EventNode> eventNodes = graphNode.getNodeEvent();
			if(CollectionUtil.isNotEmpty(eventNodes)){
				for(EventNode eventNode:eventNodes){
					String excuteStr="";
					//javaclass类型
					if(!StringUtil.isEmpty(eventNode.getEvent_type()) && "javaclass".equals(eventNode.getEvent_type())){
						excuteStr = "class='"+eventNode.getJavaclass_express()+"'";
					}
					//express类型
					if(!StringUtil.isEmpty(eventNode.getEvent_type())  && "express".equals(eventNode.getEvent_type())){
						excuteStr = " expression='"+eventNode.getJavaclass_express()+"'";
					}
					//delegateExpression类型
					if(!StringUtil.isEmpty(eventNode.getEvent_type())  && "delegateExpression".equals(eventNode.getEvent_type())){
						excuteStr = " delegateExpression='"+eventNode.getJavaclass_express()+"'";
					}

					//任务监听
					if(!MxUtils.TASKLISTENER.equals(eventNode.getCategories())){
						task_node += "<activiti:taskListener event='"+eventNode.getEvent()+"' "+excuteStr+">";
						//字段开始 子循环操作
						if(!StringUtil.isEmpty(eventNode.getEvent_type()) && ("javaclass".equals(eventNode.getEvent_type()) || "express".equals(eventNode.getEvent_type()))){
							//此时存在字段 字段位置在最后一个
							if(!StringUtil.isEmpty(eventNode.getFields())){
								FormNode fn =  JsonUtil.fromAliFastJson(eventNode.getFields(),FormNode.class);
								List<Field> fields = fn.getFields();
								if(CollectionUtil.isNotEmpty(fields)){
									for(Field field:fields){
										task_node += "<activiti:field name='"+field.getFname()+"'>";
										task_node += "<activiti:string><![CDATA["+field.getFieldValue()+"]]></activiti:string>";
										task_node += "</activiti:field>";
									}
								}
							}
						}
						//字段结束
						task_node += "</activiti:taskListener>";
					}
					//执行监听
					if(!MxUtils.EXCUTELISTENER.equals(eventNode.getCategories())){
						task_node += "<activiti:executionListener event='"+eventNode.getEvent()+"' "+excuteStr+">";
						//1-1字段开始 子循环操作
						if(!StringUtil.isEmpty(eventNode.getEvent_type()) && ("javaclass".equals(eventNode.getEvent_type()) || "express".equals(eventNode.getEvent_type()))){
							//此时存在字段 字段位置在最后一个
							if(!StringUtil.isEmpty(eventNode.getFields())){
								FormNode fn =  JsonUtil.fromAliFastJson(eventNode.getFields(),FormNode.class);
								List<Field> fields = fn.getFields();
								if(CollectionUtil.isNotEmpty(fields)){
									for(Field field:fields){
										task_node += "<activiti:field name='"+field.getFname()+"'>";
										task_node += "<activiti:string><![CDATA["+field.getFieldValue()+"]]></activiti:string>";
										task_node += "</activiti:field>";
									}
								}
							}
						}
						//1-1字段结束
						task_node += "</activiti:executionListener>";
					}

					//监听的类结束
				}
			}
        }        
        task_node+=MxUtils.form(mxCell);
        //表单配置结束
        task_node += "</extensionElements>";
        //****开始区间与闭区间属性 结束****//
		task_node += MxMultiInstanceUtils.multiInstanceNode(mxCell);//会签
		//闭区间
		task_node += "</userTask>";
		
		//连线配置开始
        task_node+= MxUtils.sequenceFlow(root, mxCellList, mxCell);
        //连线配置结束
        /////////////////////判断其下面是否拥有（时间边界，消息边界，补偿边界，信号边界）等节点
        Map<String,Object> map = MxUtils.resultTaskChildBpmn(root, mxCellList, mxCell,1);
        if(null != map && "".equals(map) && !map.isEmpty()){
        	 task_node += map.get("bpmnxml");
        }
		return task_node;
	}
	
	/**
	 * 人工任务节点bpmndi
	 * @param root
	 * @param mxCellList
	 * @param mxCell
	 * @return
	 */
	public static String userTaskBpmndi(Element root,List mxCellList,Element mxCell){
		String nodeID = mxCell.attributeValue("nodeID");
		String id = mxCell.attributeValue("id");
		Map<String, Object> xyMap = MxUtils.resultBoundsXY(mxCellList, mxCell);
        String x = xyMap.get("x").toString();
        String y = xyMap.get("y").toString();
        String width = xyMap.get("width").toString();
        String height = xyMap.get("height").toString();
		String bpmndi="";
		bpmndi += "<bpmndi:BPMNShape bpmnElement='"+nodeID+"' id='BPMNShape_"+nodeID+"'>";
        bpmndi += "<omgdc:Bounds height='"+height+"' width='"+width+"' x='"+x+"' y='"+y+"'></omgdc:Bounds>";
        bpmndi += "</bpmndi:BPMNShape>";
        //再次进行循环 目的获取连接线
		for(int j = 0; j < mxCellList.size(); j++ ){
			//mxCell节点
            Element mxCell_agin = (Element) mxCellList.get(j); 
            //该mxCell节点为连线节点情况
            if(null != mxCell_agin.attributeValue("edge") && !"".equals(mxCell_agin.attributeValue("edge"))){
            	//如果第一层循环中的ID等于第二层循环中的source则说明开始节点有指向其他节点连线
            	String source = mxCell_agin.attributeValue("source");
            	if(source.equals(id)){
            		//此时需要取出target即目标节点ID的属性value
            		List target_target_list = root.selectNodes("/root/mxCell[@id='"+mxCell_agin.attributeValue("target")+"']");
        			if(!target_target_list.isEmpty()){
        				//任务节点可以连接多个节点即一个任务节点可以有多条连接线
        				for(int l = 0; l < target_target_list.size(); l++){
        					Element mxCell_target = (Element)target_target_list.get(l);
            				if("startEvent".equals(mxCell_target.attributeValue("node_type"))){
            					//提示
								log.info("任务节点连线不能指向开始节点");
            					//该地方需要终止
            				}else{
            					bpmndi += "<bpmndi:BPMNEdge bpmnElement='"+mxCell_agin.attributeValue("nodeID")+"' id='BPMNEdge_"+mxCell_agin.attributeValue("nodeID")+"'>";
            					bpmndi += MxUtils.resultChildEdgeXy(mxCellList,mxCell_agin);
            					bpmndi += "</bpmndi:BPMNEdge>";
            				}
        				}
        			}
            	}
            }
		}
		/////////////////////判断其下面是否拥有（时间边界，消息边界，补偿边界，信号边界）等节点
        Map<String,Object> map = MxUtils.resultTaskChildBpmn(root, mxCellList, mxCell,1);
        if(null != map && "".equals(map) && !map.isEmpty()){
        	bpmndi += map.get("bpmndi");
        }
		return bpmndi;
	}
}
